# USAGE
# python real_time_object_detection.py --prototxt MobileNetSSD_deploy.prototxt.txt --model MobileNetSSD_deploy.caffemodel

import time

from imutils.video import VideoStream
from imutils.video import FPS
import numpy as np
import imutils
import cv2

import face_detect

# path to Caffe 'deploy' prototxt file
PROTOTXT = 'MobileNetSSD_deploy.prototxt.txt'

# path to Caffe pre-trained model
MODEL = 'MobileNetSSD_deploy.caffemodel'

# minimum probability to filter weak detections
CONFIDENCE = 0.2



# initialize the list of class labels MobileNet SSD was trained to
# detect, then generate a set of bounding box colors for each class
CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat",
           "bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
           "dog", "horse", "motorbike", "person", "pottedplant", "sheep",
           "sofa", "train", "tvmonitor"]

# NEED_CLASSES = set(['car', 'person'])
NEED_CLASSES = set(CLASSES)

COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3))

# load our serialized model from disk
print("[INFO] loading model...")
net = cv2.dnn.readNetFromCaffe(PROTOTXT, MODEL)


def process_frame(frame, save_face=False):
    frame = imutils.resize(frame, width=800)

    # grab the frame dimensions and convert it to a blob
    (h, w) = frame.shape[:2]
    print('after process: h, w = %d %d' % (h, w))
    blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)),
                                 0.007843, (300, 300), 127.5)

    # pass the blob through the network and obtain the detections and
    # predictions
    net.setInput(blob)
    detections = net.forward()

    # loop over the detections
    # eg:
    # [[[[0.          9.          0.42181703  0.4647404   0.610577
    #     0.6360997   0.8479532]
    #    [0.         15.          0.8989926   0.21603307  0.42735672
    #    0.58441484  0.8699994]]]]
    for i in np.arange(0, detections.shape[2]):
        # extract the confidence (i.e., probability) associated with
        # the prediction
        confidence = detections[0, 0, i, 2]

        # filter out weak detections by ensuring the `confidence` is
        # greater than the minimum confidence
        if confidence > CONFIDENCE:
            # extract the index of the class label from the
            # `detections`, then compute the (x, y)-coordinates of
            # the bounding box for the object
            idx = int(detections[0, 0, i, 1])
            box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
            (startX, startY, endX, endY) = box.astype("int")
            # print('startX, startY, endX, endY', startX, startY, endX, endY)

            class_name = CLASSES[idx]
            if class_name in NEED_CLASSES:
                if class_name == 'person':
                    face_detect.face_detect(frame[startY: endY, startX: endX])
                # draw the prediction on the frame
                label = "{}: {:.2f}%".format(class_name,
                                             confidence * 100)
                cv2.rectangle(frame, (startX, startY), (endX, endY),
                              COLORS[idx], 2)
                y = startY - 15 if startY - 15 > 15 else startY + 15
                cv2.putText(frame, label, (startX, y),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)
    return frame


if __name__ == '__main__':

    # initialize the video stream, allow the cammera sensor to warmup,
    # and initialize the FPS counter
    print("[INFO] starting video stream...")
    video_file = r'data\video\test_video.flv'
    url = 'rtmp://58.200.131.2:1935/livetv/hunantv'
    vs = VideoStream(url).start()
    # vs = VideoStream(video_file).start()
    time.sleep(2.0)
    fps = FPS().start()

    # loop over the frames from the video stream
    while True:
        # grab the frame from the threaded video stream and resize it
        # to have a maximum width of 400 pixels
        frame = vs.read()
        if frame is None:
            exit('Video Input Error! 输入错误！')
        frame = process_frame(frame)

        # show the output frame
        cv2.imshow("Frame", frame)
        key = cv2.waitKey(1) & 0xFF

        # if the `q` key was pressed, break from the loop
        if key == ord("q"):
            break

        # update the FPS counter
        fps.update()

    # stop the timer and display FPS information
    fps.stop()
    print("[INFO] elapsed time: {:.2f}".format(fps.elapsed()))
    print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

    # do a bit of cleanup
    cv2.destroyAllWindows()
    vs.stop()
